#include "monitor_widget.h"

namespace monitor {

MonitorWidget::MonitorWidget(QWidget *parent) {}

  QWidget *MonitorWidget::ShowAllMonitorWidget(const std::string& name) {
  // showAllMonitor 是将所有布局融合在一起。
  // 创建一个新窗口 
  // Qwiget 是窗口类。 layout是布局窗口的类 。布局类。
  // Qt提供了几种不同类型的布局管理器，包括 QVBoxLayout（垂直布局）、QHBoxLayout（水平布局）、QGridLayout（网格布局）等。 
  // Qwidget 与 layout是相互包含的关系：Qwidget 可以通过setLayout来包含layout。Layout可以通过addWidget 来包含widget ； 
  QWidget *widget = new QWidget();
  // QstackLayout继承自Qlayout ,QstackLayout  类提供多页面切换。一次只能看到一个页面
  
  stack_menu_ = new QStackedLayout();
  // 设置这些页面一次只能看到一个 用于之后在点击按钮后，触发的事件
  stack_menu_->addWidget(InitCpuMonitorWidget());
  // 设置这些页面一次只能看到一个 用于之后在点击按钮后，触发的事件
  stack_menu_->addWidget(InitSoftIrqMonitorWidget());
  // 设置这些页面一次只能看到一个 用于之后在点击按钮后，触发的事件
  stack_menu_->addWidget(InitMemMonitorWidget());
  // 设置这些页面一次只能看到一个 用于之后在点击按钮后，触发的事件
  stack_menu_->addWidget(InitNetMonitorWidget());

  QGridLayout *layout = new QGridLayout(this);
  // 总的页面的显示第1行第0列显示按钮 
  layout->addWidget(InitButtonMenu(name), 1, 0);
  // 多页面切换的布局是在第2行第0列。 
  layout->addLayout(stack_menu_, 2, 0);
  
  widget->setLayout(layout);
  return widget; // 再返回窗口
}

QWidget *MonitorWidget::InitButtonMenu(const std::string& name) {
  // 1.设置按钮。2.设置按钮的字体。3. 设置一个新窗口，为新窗口设置新布局按钮。4.将按钮的信号设置为点击信号

  // char *name = getenv("USER");
  // 这个是按钮点击后会触发信号，有普通按钮，单选按钮。 等 这里使用普通按钮
  // 初始化按钮。
  // Qwiget 是窗口类。 layout是布局窗口的类 。布局类。Qt提供了几种不同类型的布局管理器，包括 QVBoxLayout（垂直布局）、QHBoxLayout（水平布局）、QGridLayout（网格布局）等。 
  // Qwidget 与 layout是相互包含的关系：Qwidget 可以通过setLayout来包含layout。Layout可以通过addWidget 来包含widget ； 
  QPushButton *cpu_button = new QPushButton(QString::fromStdString(name) + "_cpu", this);
  QPushButton *soft_irq_button = new QPushButton(QString::fromStdString(name) + "_soft_irq", this);
  QPushButton *mem_button = new QPushButton(QString::fromStdString(name) + "_mem", this);
  QPushButton *net_button = new QPushButton(QString::fromStdString(name) + "_net", this);
  // 设置按钮的字体。 
  QFont *font = new QFont("Microsoft YaHei", 15, 40);
  cpu_button->setFont(*font);
  soft_irq_button->setFont(*font);
  mem_button->setFont(*font);
  net_button->setFont(*font);
  // 按钮布局QHBoxLayout 表示水平布局。横着布局的。所以在QT界面有cpu， soft_irq , mem , net 四个 按键 。 
  QHBoxLayout *layout = new QHBoxLayout();
  layout->addWidget(cpu_button);
  layout->addWidget(soft_irq_button);
  layout->addWidget(mem_button);
  layout->addWidget(net_button);
  // 设置一个新窗口目的使用按钮的布局布局也要设置。 
  QWidget *widget = new QWidget();
  widget->setLayout(layout);
  // 把信号传送到ClickCpuButton 函数里面
  connect(cpu_button, SIGNAL(clicked()), this, SLOT(ClickCpuButton()));
  // 把信号传送到ClickSoftIrqButton 函数里面
  connect(soft_irq_button, SIGNAL(clicked()), this, SLOT(ClickSoftIrqButton()));
  // 把信号传送到ClickMemButton 函数里面
  connect(mem_button, SIGNAL(clicked()), this, SLOT(ClickMemButton()));
  // 把信号传送到ClickNetButton 函数里面
  connect(net_button, SIGNAL(clicked()), this, SLOT(ClickNetButton()));

  return widget;
}

QWidget *MonitorWidget::InitCpuMonitorWidget() {
  QWidget *widget = new QWidget();
  // QLabel 
  QLabel *cpu_load_label = new QLabel(this);
  //tr表示从词翻译过去的。
  cpu_load_label->setText(tr("Monitor CpuLoad:"));
  cpu_load_label->setFont(QFont("Microsoft YaHei", 10, 40));
  cpu_load_monitor_view_ = new QTableView;
  cpu_load_model_ = new CpuLoadModel;
  // 设置每列是可排序 
  // QSortFilterProxyModel *sort_proxy = new QSortFilterProxyModel(this);
  // sort_proxy->setSourceModel(cpu_load_model_);
  // cpu_load_monitor_view_->setModel(sort_proxy);
  // cpu_load_monitor_view_->setSortingEnabled(true) ; 
  cpu_load_monitor_view_->setModel(cpu_load_model_);
  cpu_load_monitor_view_->show(); // show会去调用

  QLabel *cpu_stat_label = new QLabel(this);
  cpu_load_label->setText(tr("Monitor CpuStat:"));
  cpu_load_label->setFont(QFont("Microsoft YaHei", 10, 40));

  cpu_stat_monitor_view_ = new QTableView;
  cpu_stat_model_ = new CpuStatModel;
  cpu_stat_monitor_view_->setModel(cpu_stat_model_);  // 将模型插入到cpu_stat_monitor_view表格中 ，将数据进行填充
  cpu_stat_monitor_view_->show();

  QGridLayout *layout = new QGridLayout();
  // 表示在3行0列放置窗口 大小为默认。 
  layout->addWidget(cpu_load_label, 3, 0);
  // 在4行0列放置窗口 大小为横为2个单位竖为2个单位。 
  layout->addWidget(cpu_load_monitor_view_, 4, 0, 2, 2);
  // 在1行0列放置窗口 大小为横为1个单位竖为1个单位。 
  layout->addWidget(cpu_stat_label, 1, 0, 1, 1);
   // 在2行0列放置窗口 大小为横为1个单位竖为2个单位。 
  layout->addWidget(cpu_stat_monitor_view_, 2, 0, 1, 2);

  widget->setLayout(layout);
  return widget;
}

QWidget *MonitorWidget::InitSoftIrqMonitorWidget() {
  QWidget *widget = new QWidget();
  QLabel *monitor_label = new QLabel(this);
  monitor_label->setText(tr("Monitor softirq:"));
  monitor_label->setFont(QFont("Microsoft YaHei", 10, 40));

  monitor_view_ = new QTableView;
  monitor_model_ = new MonitorBaseModel;
  // 将每列设置为可排序的。 
  QSortFilterProxyModel *sort_proxy = new QSortFilterProxyModel(this);
  sort_proxy->setSourceModel(monitor_model_); 
  monitor_view_->setModel(sort_proxy);   // 将模型插入到monitor_view表格中 对数据进行填充
  monitor_view_->setSortingEnabled(true);
    // Qtableview的show会调用 继承自QAbstractTableModel  的数据模型的data 并且传参给QModelIndex 和 int role = Qt::DisplayRole 为默认参数； 
  //调用rowCount ， columnCount ，headerData 等函数。 来显示数据。 
  monitor_view_->show();

  QGridLayout *layout = new QGridLayout();
  layout->addWidget(monitor_label, 1, 0);
  // 在2行0列放置窗口，大小为1行2列。
  layout->addWidget(monitor_view_, 2, 0, 1, 2); 

  widget->setLayout(layout);
  return widget;
}
//在这里窗口的设计的注释 
QWidget *MonitorWidget::InitMemMonitorWidget() {
  QWidget *widget = new QWidget();

  QLabel *mem_label = new QLabel(this);
  mem_label->setText(tr("Monitor mem:"));
  mem_label->setFont(QFont("Microsoft YaHei", 10, 40));

  //创建表格对象， 
  mem_monitor_view_ = new QTableView;
  mem_model_ = new MemModel;

  //之后将数据填到表格中。
  mem_monitor_view_->setModel(mem_model_);  // 将模型插入到net_monitor_view表格中 对数据进行填充
  mem_monitor_view_->show();

  QGridLayout *layout = new QGridLayout();
  // 排版格式：在第一行第0列添加mem_label。
  layout->addWidget(mem_label, 1, 0);
  // 排版格式：第二行添加 mem_monitor_view_。第2行，第0列， 横为1个单位，竖为1个单位
  layout->addWidget(mem_monitor_view_, 2, 0, 1, 1);
  // 然后设置到布局
  widget->setLayout(layout);
  // 返回这个窗口
  return widget;
}

QWidget *MonitorWidget::InitNetMonitorWidget() {
  QWidget *widget = new QWidget();

  QLabel *net_label = new QLabel(this);
  net_label->setText(tr("Monitor net:"));
  net_label->setFont(QFont("Microsoft YaHei", 10, 40));

  net_monitor_view_ = new QTableView;
  net_model_ = new NetModel;
  net_monitor_view_->setModel(net_model_);  // 将模型插入到net_monitor_view表格中 对数据进行填充
  net_monitor_view_->show();

  QGridLayout *layout = new QGridLayout();

  layout->addWidget(net_label, 1, 0);
  layout->addWidget(net_monitor_view_, 2, 0, 1, 1);

  widget->setLayout(layout);
  return widget;
}

void MonitorWidget::UpdateData(
    const monitor::proto::MonitorInfo &monitor_info) {
    // 将每个模型的数据刷新一遍
  monitor_model_->UpdateMonitorInfo(monitor_info);
  cpu_load_model_->UpdateMonitorInfo(monitor_info);
  cpu_stat_model_->UpdateMonitorInfo(monitor_info);
  mem_model_->UpdateMonitorInfo(monitor_info);
  net_model_->UpdateMonitorInfo(monitor_info);
}
// 点击事件后会发生切换设置到0号页面的事件 。 
void MonitorWidget::ClickCpuButton() { stack_menu_->setCurrentIndex(0); } 
// 点击事件后会发生切换设置到1号页面的事件 。  
void MonitorWidget::ClickSoftIrqButton() { stack_menu_->setCurrentIndex(1); }
// 点击事件后会发生切换设置到2号页面的事件 。
void MonitorWidget::ClickMemButton() { stack_menu_->setCurrentIndex(2); }
// 点击事件后会发生切换设置到3号页面的事件 。
void MonitorWidget::ClickNetButton() { stack_menu_->setCurrentIndex(3); }
}  // namespace monitor
